package com.cy.detectsys.service;

import cn.hutool.core.util.StrUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cy.detectsys.entity.DetectTarget;
import com.cy.detectsys.mapper.DetectTargetMapper;
import com.cy.detectsys.model.PageDto;
import com.cy.detectsys.model.req.TargetRequestParam;
import com.cy.detectsys.util.R;
import jakarta.annotation.Resource;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.SearchHits;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.*;

@Service
public class ContentService {

    @Resource
    private RestHighLevelClient restHighLevelClient;
    @Resource
    private DetectTargetIpService targetIpService;

    public List<Map<String, Object>> highlightSearch(String keyword, Integer pageIndex, Integer pageSize) throws IOException, IOException {
        SearchRequest searchRequest = new SearchRequest("bulk");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 精确查询，添加查询条件
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
        searchSourceBuilder.query(termQueryBuilder);
        // 分页
        searchSourceBuilder.from(pageIndex);
        searchSourceBuilder.size(pageSize);
        // 高亮 =========
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);
        // 执行查询
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        // 解析结果 ==========
        SearchHits hits = searchResponse.getHits();
        List<Map<String, Object>> results = new ArrayList<>();
        for (SearchHit documentFields : hits.getHits()) {
            // 使用新的字段值（高亮），覆盖旧的字段值
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            // 高亮字段
            Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            // 替换
            if (name != null) {
                Text[] fragments = name.fragments();
                StringBuilder new_name = new StringBuilder();
                for (Text text : fragments) {
                    new_name.append(text);
                }
                sourceAsMap.put("name", new_name.toString());

            }
            results.add(sourceAsMap);
        }
        return results;
    }


    @Resource
    private DetectTargetMapper detectTargetMapper;

    @DS("detect")
    public R highlightSearch(TargetRequestParam taskReq, String indexName, List<String> fields, Integer pageIndex, Integer pageSize) throws IOException {

        String companyName = taskReq.getCompanyName();
        String domain = taskReq.getDomain();

//        if (StrUtil.isEmpty(companyName) && StrUtil.isEmpty(domain)) {
//            return R.error("目标查询条件未提交");
//        }

        QueryWrapper<DetectTarget> tbNetTargetQueryWrapper = new QueryWrapper<>();
        if (StrUtil.isNotEmpty(taskReq.getKeyword())) {
            tbNetTargetQueryWrapper.like("ky_net_target_english_name", taskReq.getKeyword()).or()
                    .like("ky_net_target_domain", taskReq.getKeyword());

        } else {
            if (StrUtil.isNotEmpty(companyName)) {
                tbNetTargetQueryWrapper.like("ky_net_target_english_name", companyName.trim());
            }
            if (StrUtil.isNotEmpty(domain)) {
                tbNetTargetQueryWrapper.like("ky_net_target_domain", domain.trim());
            }
        }

        //主线查询target表
        //PageHelper.startPage(pageIndex, pageSize);
        List<DetectTarget> tbNetTargets = detectTargetMapper.selectList(tbNetTargetQueryWrapper);


        for (DetectTarget tbNetTarget : tbNetTargets) {
            queryTargetContract(tbNetTarget, taskReq.getKeyword(), indexName, fields);
        }


        return R.ok(PageDto.listToPageDto(tbNetTargets));
    }

    private void queryTargetContract(DetectTarget target, String keyword, String indexName, List<String> fields) throws IOException {
        SearchRequest searchRequest = new SearchRequest(indexName);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 构建一个布尔查询，用于在多个字段中搜索关键词
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();


        if (StrUtil.isEmpty(keyword)) {
            keyword = target.getKyNetTargetEnglishName();
        }

        for (String field : fields) {
            boolQueryBuilder.should(QueryBuilders.matchQuery(field, keyword));
        }


        searchSourceBuilder.query(boolQueryBuilder);

        // 设置查询的超时时间


        // 高亮显示
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        for (String field : fields) {
            highlightBuilder.field(field).preTags("<span style='color:red'>").postTags("</span>");
        }
        searchSourceBuilder.highlighter(highlightBuilder);

        // 执行查询
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // 解析结果
        SearchHits hits = searchResponse.getHits();
        List<Map<String, Object>> results = new ArrayList<>();
        for (SearchHit hit : hits.getHits()) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            Set<String> foundField = new HashSet<>();

            // 遍历所有指定的字段，并将高亮显示的内容替换到结果中
            for (String field : fields) {
                HighlightField highlightField = hit.getHighlightFields().get(field);
                if (highlightField != null) {
                    Text[] fragments = highlightField.fragments();
                    StringBuilder highlightedContent = new StringBuilder();
                    for (Text fragment : fragments) {
                        highlightedContent.append(fragment);
                    }
                    sourceAsMap.put(field, highlightedContent.toString());

                    // 这里是能找到 关键次的字段
                    foundField.add(field);


                }
            }
            sourceAsMap.put("found", foundField);


            results.add(sourceAsMap);
        }
        target.setSourceAsMap(results);
        target.setFoundCount(results.size());
        String targetNameEn = target.getKyNetTargetEnglishName();
        HashMap<String, List<String>> targetIP = targetIpService.selectByTargetName(targetNameEn);

        List<String> domains = targetIP.get("domains");

        List<String> ips = targetIP.get("ips");

        target.setDomains(domains);
        target.setIps(ips);


    }
}
